#encoding=utf8
import Image
import cStringIO
import httplib
import os
import uuid
import swfheader
import mmap
import mimetypes
from trp.models import MaterialType
from website.settings import MATERIAL
from website.settings import LOGGER as logger

class MaterialUploadHandler():
    processor=None

    def set_processor(self, processor):
        self.processor = processor
        return self.processor

    def handle(self,req):
        """
        处理上传请求
        """
        raise NotImplementedError("please implement this method")

    def get_material_type_id(self,name):
        """
        根据物料类型名称获取物料类型信息
        """
        try:
            name= name.upper()
            t = MaterialType.objects.get(name=name)
            return t.id
        except :
            pass
        return None
    
    def upload_to_remote(self,req):
        """
        删除物料到远程服务器，返回服务器响应字符串
        """
        responseStr=""
        if req.file:
            conn=None
            response = None
            fd=None
            try :
                conn = httplib.HTTPConnection(MATERIAL["host"], int(MATERIAL["port"]), int(MATERIAL["timeout"]))
                upload_url=os.path.join(MATERIAL["upload_url"],req.format.lower())
                TMP_DIR=MATERIAL["tmp_dir"]
                try :
                    if not os.path.exists(TMP_DIR):
                        os.makedirs(TMP_DIR)
                except :
                    logger.info("create tmp dir(%s) error"%TMP_DIR)
                    raise Exception("can not create directory:%s"%TMP_DIR) 
                filename = uuid.uuid4().hex+"."+req.format.lower()
                fd= open(os.path.join(TMP_DIR,filename),"wb")
                for chunck in req.file.chunks():
                    fd.write(chunck)
                fd.close()

                fd=open(os.path.join(TMP_DIR,filename),"rb")
                mmaped_file = mmap.mmap(fd.fileno(), 0, access=mmap.ACCESS_READ)

                try :
                    content_type = mimetypes.guess_type(filename)[0] or 'application/octet-stream' 
                    conn.putrequest('POST', upload_url)
                    conn.putheader('content-type',content_type)
                    conn.putheader('content-length', str(len(mmaped_file)))
                    conn.putheader("")
                    conn.endheaders()
                    conn.send(mmaped_file)
#                     conn.request("POST", upload_url,fd, headers)
                    response = conn.getresponse()
                except :
                    msg = "can't connect to material server,host:%s:%d"%(MATERIAL["host"],MATERIAL["port"])
                    logger.info(msg)
                    raise Exception(msg)
    
                if response.status ==200 :
                    responseStr = response.read()
                    if not responseStr.startswith("http://") :
                        responseStr = "".join(["http://",responseStr])
                    print "url :",responseStr
                elif response.status ==404 :
                    msg = "material format %s not allowed "%req.format
                    logger.info(msg)
                    raise Exception(msg)
            finally:
                if mmaped_file :
                    mmaped_file.close()
                if fd :
                    fd.close()
                    os.remove(fd.name)
                if conn:
                    conn.close()
        else :
            raise Exception("material is null")
        return responseStr 
        
        
class ImgUploadHandler(MaterialUploadHandler):
    def handle(self,req):
        if req.format in (MATERIAL["img_format"] or ["JPG","GIF","PNG","BMP"]):
            img = Image.open(cStringIO.StringIO(req.file.read()))

            url = self.upload_to_remote(req)

            result={
                    "width":img.size[0],
                    "height":img.size[1],
                    "name":req.file.name,
                    "size":req.file.size,
                    "type":self.get_material_type_id(req.format),
                    "url":url
            }
            return result
        elif self.processor :
            return self.processor.handle(req)
        else :
            raise Exception("can not handle this file")

class FlashUploadHandler(MaterialUploadHandler):
    def handle(self,req):
        if req.format in (MATERIAL["flash_format"] or ["SWF"]):
            header = swfheader.parse(req.file)
            url = self.upload_to_remote(req)
            
            result={
                    "width":header['width'],
                    "height":header['height'],
                    "name":req.file.name,
                    "size":req.file.size,
                    "type":self.get_material_type_id(req.format),
                    "url":url
            }
            return result
        elif self.processor:
            return self.processor.handle(req)
        else :
            raise Exception("can not handle this file")
        def __handle__(self,req):
            pass


class VideoUploadHandler(MaterialUploadHandler):
    pass 

class HtmlUploadHandler(MaterialUploadHandler):
    def handle(self,req):
        if req.format in (MATERIAL["html_format"]or['HTML','HTM']):
            url = self.upload_to_remote(req)
            result={
                "format":"html",
                "name":req.file.name,
                "size":req.file.size,
                "type":self.get_material_type_id(req.format),
                "url":url
            }
            return result
        elif self.processor:
            return self.processor.handle(req)
        else :
            raise Exception("can not handle this file")
class UploadRequest:
    def __init__(self,file_obj):
        """
        file_obj 是django上传的接收文件，类型为UploadedFile
        """
        self.file=file_obj
        if file_obj :
            filename = file_obj.name
            self.format=filename[filename.rindex(".")+1:].upper()
        
